package com.itheima.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.itheima.common.PageInfo;
import com.itheima.dto.DishDto;
import com.itheima.dto.FlavorDto;
import com.itheima.mapper.CategoryMapper;
import com.itheima.mapper.DishMapper;
import com.itheima.pojo.Category;
import com.itheima.pojo.Dish;
import com.itheima.pojo.DishFlavor;
import com.itheima.service.DishService;
import com.itheima.thread.TokenThreadUtils;
import com.itheima.vo.DishByIdVo;
import com.itheima.vo.DishListVo;
import com.itheima.vo.DishVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class DishServiceImpl implements DishService {


    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    //添加菜品
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean addDish(DishDto dishDto) {
        //雪花id
        String id = IdUtil.getSnowflakeNextIdStr();
        dishDto.setId(id);
        //把前端传过来的参数，对应写到它的表中
        //菜品信息 -> 菜品表
        //1.把Dish中属于菜品的东西提取出来，放到Dish实体类里面
        Dish dish = new Dish();
        //拷贝同名和同类型的字段值
        BeanUtils.copyProperties(dishDto, dish);

        //获取当前用户id
        String cuid = TokenThreadUtils.threadLocal.get().getId();
        //添加创建菜品的用户id
        dish.setCreateUser(cuid);


        //2.调用dish表insert方法，写入这部分信息
        int res = dishMapper.addDish(dish);


        //口味信息 -> 口味表
        //1.获取当前菜品口味集合
        List<FlavorDto> flavors = dishDto.getFlavors();
        //判空
        //如果用循环+插入的方式，当我调用一次接口后，就会重复执行多次sql操作
        //导致性能下降
        List<DishFlavor> newlist = new ArrayList<>();
        if (!CollectionUtil.isEmpty(flavors)) {
            //2.遍历集合并且插入到数据库中
            for (FlavorDto item : flavors) {
                if (item == null) {
                    continue;
                }
                //dish_clavor    id雪花数
                String id2 = IdUtil.getSnowflakeNextIdStr();

                //2.1将接收到的参数 转成Flavor结构
                DishFlavor flavor = new DishFlavor();

                BeanUtils.copyProperties(item, flavor);
                //设置口味id
                flavor.setId(id2);
                //设置菜品id
                flavor.setDishId(id);

                flavor.setUpdateTime(LocalDateTime.now());

                //添加创建口味的用户id
                flavor.setCreateUser(cuid);
                //添加修改口味的用户id
                flavor.setUpdateUser(cuid);
//                System.out.println("===================================");
//                log.info("{}",flavor);
//                System.out.println("===================================");

                newlist.add(flavor);
                //2.2执行insert插入到数据库中    导致性能下降的旧操作↓
//                int res2 = dishMapper.adddishFlavor(flavor);
//                if (res2!=1){
//                    throw new RuntimeException("口味添加失败");
//                }
            }
            //3.返回结果
        }
        //2.2执行insert插入到数据库中   优化后的操作↓
        int rs = dishMapper.batchInsertFlavor(newlist);
        if (rs != newlist.size()) {
            throw new RuntimeException("口味添加失败");
        }


        return res == 1;
    }

    //分页查询菜品    下面的<Dish>是因为PageInfo自定义了一个泛型<T>
    @Override
    public PageInfo<DishVo> page(String name, Integer page, Integer pageSize) {
        //创建一个容器
        PageInfo<DishVo> pageInfo = new PageInfo<DishVo>();
        //分页公式    第几页 = （第几页-1） * 一页的个数
        Integer start = (page - 1) * pageSize;
        List<DishVo> dishes = dishMapper.page(name, start, pageSize);

        //找到分类名称写入页面
        for (DishVo dish : dishes) {
            Category categoryById = categoryMapper.getCategoryById(dish.getCategoryId());
            String categoryName = categoryById.getName();
            dish.setCategoryName(categoryName);
        }

        //records：当前页面内容，是个数组[]
        pageInfo.setRecords(dishes);
        //size：每页显示条数
        pageInfo.setSize(pageSize);
        //current：当前页码
        pageInfo.setCurrent(page);

        //计算 total(总条数)(通过名字) 的方法
        long count = dishMapper.countDish();

        //total：总条数
        pageInfo.setTotal(count);
        return pageInfo;


    }

    //菜品下拉列表
    @Override
    public List<DishListVo> getList(String categoryId) {
        List<DishListVo> list = dishMapper.getlist(categoryId);
        return list;
    }


    //根据id查询菜品信息
    @Override
    public DishByIdVo getDishById(String id) {
        //调用根据id查询菜品（无口味）  并 将返回值写入DishByIdVo
        DishByIdVo dishById = dishMapper.getDishById(id);

        //获取口味   注：sql语句内，要通过dish_flavor的dish_id去匹配传入的菜品id
        List<FlavorDto> flavorDtos = dishMapper.dishFlavorById(id);


        //将口味添加进去DishByIdVo
        dishById.setFlavors(flavorDtos);
        return dishById;
    }

    //修改菜品
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean updateDish(DishDto dishDto) {
        if (dishDto == null) {
            throw new RuntimeException("参数不能为空");
        }

        //1.提取菜品信息，覆盖到菜品里面
        //2创建一个dish对象和dishFlavor对象
        Dish dish = new Dish();
        DishFlavor dishFlavor = new DishFlavor();

        //2.1从dishDto中提取菜品相关数据，封装到dish对象中
        BeanUtils.copyProperties(dishDto, dish);
        //设置修改用户id
        String cuid = TokenThreadUtils.threadLocal.get().getId();


        dish.setCreateUser(cuid);
        //设置修改时间
        dish.setUpdateTime(LocalDateTime.now());

        //2.2从dishDto中提取菜品相关数据，封装到dishFlavor对象中
        BeanUtils.copyProperties(dishDto, dishFlavor);

//        //移动到下面集合添加方法内
//        //设置主键（雪花id）
//        String dishFlavorId = IdUtil.getSnowflakeNextIdStr();
//        dishFlavor.setId(dishFlavorId);
//        //设置添加和修改用户id
//        dishFlavor.setUpdateUser(cuid);
//        dishFlavor.setCreateUser(cuid);
//        //设置修改时间
//        dishFlavor.setUpdateTime(LocalDateTime.now());

        //3.1调用mapper，update菜品信息
        int updateDishRes = dishMapper.updateDish(dish);
        if (updateDishRes != 1) {
            log.error("菜品修改失败");
            return false;
        }
        //3.1.1更新菜品与口味的关系
        int total = dishMapper.countFlavorByDishId(dishDto.getId());
        if (total > 0) {
            //3.1.2根据菜品id删除所有关联的口味信息
            int removeRes = dishMapper.removeFlavorByDishId(dishDto.getId());
            if (removeRes != total) {
                log.error("菜品口味删除失败");
                return false;
            }
        }

        //3.2将dishDto中的口味信息添加到口味表中
        //口味信息 -> 口味表
        //1.获取当前菜品口味集合
        List<FlavorDto> flavors = dishDto.getFlavors();
        //判空
        //如果用循环+插入的方式，当我调用一次接口后，就会重复执行多次sql操作
        //导致性能下降
        List<DishFlavor> newlist = new ArrayList<>();
        if (!CollectionUtil.isEmpty(flavors)) {
            //2.遍历集合并且插入到数据库中
            for (FlavorDto item : flavors) {
                if (item == null) {
                    continue;
                }


                //2.1将接收到的参数 转成Flavor结构
                DishFlavor flavor = new DishFlavor();
                BeanUtils.copyProperties(item, flavor);
                flavor.setId(IdUtil.getSnowflakeNextIdStr());
                flavor.setDishId(dish.getId());
                flavor.setCreateUser(cuid);
                flavor.setUpdateUser(cuid);
                newlist.add(flavor);
                //2.2执行insert插入到数据库中    导致性能下降的旧操作↓
//                int res2 = dishMapper.adddishFlavor(flavor);
//                if (res2!=1){
//                    throw new RuntimeException("口味添加失败");
//                }
            }
            //3.返回结果
        }
        //2.2执行insert插入到数据库中   优化后的操作↓
        int rs = dishMapper.batchInsertFlavor(newlist);
        if (rs != newlist.size()) {
            throw new RuntimeException("口味添加失败");
        }


//        //2. 提取口味信息，检测哪些口味是新增的
//        //2.1 从dishDto中提取出flavor列表
//        List<FlavorDto> flavors = dishDto.getFlavors();
//        //CollectionUtils.isEmpty   集合判空
//        if (!CollectionUtils.isEmpty(flavors)) {
//            //执行删除关系
//
//            //retuen
//        }
//        //2.2 遍历列表信息，提取flavor名称
//        for (FlavorDto flavor : flavors) {
//            if (flavor==null){//如果没有口味信息，跳过
//                continue;
//            }
//            String name = flavor.getName();
//            if (StringUtils.isEmpty(name)){
//                continue;
//            }
//            //2.3 调用seleteByName查询这个名称是否存在于口味表中
//            DishFlavor dishFlavor = dishMapper.selectFlavorByName(name);
//            if (dishFlavor == null){
//                //2.4 如果不存在，则调用add方法插入口味
//                dishMapper.adddishFlavor(dishFlavor);
//            }
//        }
//
//        //3. 重建菜品和口味的关系
//
//        //3.1删除原来的口味关系
//        dishMapper.deleteByDishId(dishDto.getId());
//
//        //3.2把新的口味关系添加到关系表中
//        //入参是一个集合    菜品id   口味id
//        dishMapper.batchInsertRelation();


        return true;
    }


    //删除菜品
    @Override
    @Transactional
    public boolean deleteDish(List<String> ids) {
        //删除菜品
        boolean res = dishMapper.deleteDish(ids);
        //删除菜品对应的口味
        dishMapper.deleteDishFlavor(ids);
        return res;
    }

    //菜品停售/起售
    @Override
    public boolean status(Integer status, List<String> ids) {
        boolean res = dishMapper.status(status, ids);
        return res;
    }

    @Override
    public List<DishListVo> getMobileList(String categoryId, Integer status, Integer page, Integer pageSize) {

        //入参判断
        if (StringUtils.isEmpty(categoryId) || Objects.isNull(status)) {
            return new ArrayList<>();
        }
        page = (page - 1) * pageSize;
        List<DishListVo> dishes = dishMapper.getMobileList(categoryId, status,page,pageSize);
        if (CollectionUtil.isEmpty(dishes)){
            return new ArrayList<>();
        }
        for (DishListVo dish : dishes) {
            if (Objects.isNull(dish)){
                continue;
            }

            Category categoryById = categoryMapper.getCategoryById(categoryId);
            String categoryName = categoryById.getName();
            dish.setCategoryName(categoryName);

            //插入口味
            List<FlavorDto> flavorDtos = dishMapper.dishFlavorById(dish.getId());
            dish.setFlavors(flavorDtos);
        }

        return dishes;
    }
}
